use pyo3::prelude::*;
use crate::global_var::GLOBAL_QUEUE;
use pyo3::types::{PyList, PyDict, PyString};
use serde_json::{Value, json, Map};
use std::env; 
use crate::tasks::Message;
use std::sync::OnceLock;
use pyo3::{Python, PyResult, PyObject};
use pyo3::types::PyModule;

// 使用线程安全的存储结构
static INVESTMENT_MODULE: OnceLock<PyObject> = OnceLock::new();
static RUN_FUNCTION: OnceLock<PyObject> = OnceLock::new();

/// 运行 Python 模块并处理返回结果
#[tauri::command]
pub async fn run_task(stock_code: String) -> Result<String, String> {
    let queue = GLOBAL_QUEUE.clone();
    match setup_and_run_python(&stock_code) {
        Ok(result) => {
            let message = flatten_result(&result);
            tokio::spawn(async move {
                if let Ok(mut queue_guard) = queue.lock() {
                    queue_guard.push(json!({
                        "timestamp": chrono::Utc::now().timestamp().to_string(),
                        "topic": "task",
                        "content": message
                    }));
                }
            });
            Ok("Task completed successfully".to_string())
        }
        Err(e) => {
            let error_msg = format!("Error: {}", e);
            let queue_clone = queue.clone();
            let error_msg_clone = error_msg.clone();
            tokio::spawn(async move {
                if let Ok(mut queue_guard) = queue_clone.lock() {
                    queue_guard.push(json!({
                        "timestamp": chrono::Utc::now().timestamp().to_string(),
                        "topic": "error",
                        "content": error_msg_clone
                    }));
                }
            });
            Err(error_msg)
        }
    }
}

/// 修复 Python 字典字符串以使其兼容 JSON
fn fix_python_dict_string(s: &str) -> String {
    let mut result = s.to_string();
    
    // 替换单引号为双引号（简单替换，不处理嵌套引号）
    result = result.replace('\'', "\"");
    
    // 替换 None 为 null
    result = result.replace(" None", " null");
    result = result.replace(":None", ":null");
    
    // 替换 True/False 为 true/false
    result = result.replace(" True", " true");
    result = result.replace(":True", ":true");
    result = result.replace(" False", " false");
    result = result.replace(":False", ":false");
    
    result
}

/// 将嵌套的结果转换为扁平的消息格式
fn flatten_result(value: &Value) -> Message {
    let timestamp = chrono::Utc::now().timestamp().to_string();
        
    if let Value::Object(map) = value {
        let status = map.get("status")
            .and_then(|s| s.as_str())
            .unwrap_or("error")
            .to_string();
        
        let data = match map.get("data") {
            Some(data) => serde_json::to_string_pretty(data).unwrap_or_else(|e| e.to_string()),
            None => "No data available".to_string()
        };
        
        Message {
            timestamp,
            topic: status,
            content: data,
        }
    } else {
        Message {
            timestamp,
            topic: "error".to_string(),
            content: format!("Invalid response format: {:?}", value),
        }
    }
}

/// 设置 Python 环境并执行模块
fn setup_and_run_python(stock_code: &str) -> Result<Value, Box<dyn std::error::Error>> {
    Python::with_gil(|py| {
        // 设置 Python 路径
        setup_python_path(py)?;
        
        // 执行 Python 代码
        let result = execute_python_module(py, stock_code)?;
        
        // 处理返回值
        process_python_result(py, result).map_err(|e| Box::new(e) as Box<dyn std::error::Error>)
    })
}

/// 设置 Python 路径
fn setup_python_path(py: Python) -> Result<(), Box<dyn std::error::Error>> {
    // 获取当前目录
    let current_dir = env::current_dir().map_err(|e| {
        Box::new(std::io::Error::new(
            std::io::ErrorKind::Other,
            format!("Failed to get current directory: {}", e)
        ))
    })?;
    
    // 构建 Python 模块路径
    let base_dir = if current_dir.ends_with("src-tauri") {
        current_dir
    } else {
        current_dir.join("src-tauri")
    };
    
    let python_path = base_dir.join("lib").join("python").join("code");
    let python_path_str = python_path.to_str().ok_or_else(|| {
        Box::new(std::io::Error::new(
            std::io::ErrorKind::Other,
            "Failed to convert path to string"
        ))
    })?.to_string();
    
    // 设置 PYTHONPATH 环境变量
    env::set_var("PYTHONPATH", &python_path_str);
    
    // 将路径添加到 Python 系统路径
    let sys = py.import("sys")?;
    let _ = sys.call_method1("append", (python_path_str,))?;
    
    Ok(())
}

/// 执行 Python 模块
fn execute_python_module<'py>(
    py: Python<'py>,
    stock_code: &str
) -> PyResult<PyObject> {
    // 模块初始化
    let module = INVESTMENT_MODULE.get_or_init(|| {
        PyModule::import(py, "investment")
            .expect("Failed to import module")
            .into_py(py)
    });
    
    // 函数初始化
    let func = RUN_FUNCTION.get_or_init(|| {
        module.bind(py)
            .getattr("run")
            .expect("Function should exist")
            .into_py(py)
    });

    // 参数构建
    let py_args = (PyString::new(py, stock_code),);

    // 执行调用
    Ok(func.bind(py).call1(py_args)?.into_py(py))
}

/// 处理 Python 返回值
fn process_python_result(py: Python, py_obj: PyObject) -> PyResult<Value> {
    let py_any = py_obj.bind(py);
    
    // 如果是字典类型，直接处理
    if let Ok(dict) = py_any.downcast::<PyDict>() {
        return process_dict(py, &dict);
    }
    
    // 尝试通过 JSON 模块
    let json_module = py.import("json")?;
    if let Ok(json_str) = json_module.getattr("dumps")?.call1((py_any,)) {
        let json_string: String = json_str.extract()?;
        if let Ok(value) = serde_json::from_str(&json_string) {
            return Ok(value);
        }
    }
    
    // 如果上述方法都失败，尝试将 Python 字符串转换为 JSON
    let str_content = py_any.to_string();
    
    // 修复 Python 字典字符串
    let fixed_content = fix_python_dict_string(&str_content);
    
    // 尝试解析修复后的 JSON 字符串
    match serde_json::from_str(&fixed_content) {
        Ok(value) => Ok(value),
        Err(e) => {
            println!("Error parsing fixed content: {}", e);
            // 返回一个简单的成功响应，包含原始内容
            Ok(json!({
                "status": "success",
                "data": str_content.replace("\\n", "\n").replace("\\\"", "\"")
            }))
        }
    }
}

/// 处理 Python 字典
fn process_dict(py: Python, dict: &Bound<'_, PyDict>) -> PyResult<Value> {
    let mut map = Map::new();
    
    for item in dict.items() {
        let (key, value) = (item.get_item(0)?, item.get_item(1)?);
        let key_str = key.extract::<String>()?;
        
        // 尝试各种类型转换
        if let Ok(str_val) = value.extract::<String>() {
            map.insert(key_str, Value::String(str_val));
        } else if let Ok(int_val) = value.extract::<i64>() {
            map.insert(key_str, Value::Number(int_val.into()));
        } else if let Ok(float_val) = value.extract::<f64>() {
            if let Some(num) = serde_json::Number::from_f64(float_val) {
                map.insert(key_str, Value::Number(num));
            } else {
                map.insert(key_str, Value::Null);
            }
        } else if let Ok(bool_val) = value.extract::<bool>() {
            map.insert(key_str, Value::Bool(bool_val));
        } else if let Ok(sub_dict) = value.downcast::<PyDict>() {
            map.insert(key_str, process_dict(py, &sub_dict)?);
        } else if let Ok(list) = value.downcast::<PyList>() {
            let mut vec = Vec::new();
            for item in list.iter() {
                if let Ok(dict) = item.downcast::<PyDict>() {
                    vec.push(process_dict(py, &dict)?);
                } else if let Ok(str_val) = item.extract::<String>() {
                    vec.push(Value::String(str_val));
                } else if let Ok(int_val) = item.extract::<i64>() {
                    vec.push(Value::Number(int_val.into()));
                } else if let Ok(float_val) = item.extract::<f64>() {
                    if let Some(num) = serde_json::Number::from_f64(float_val) {
                        vec.push(Value::Number(num));
                    } else {
                        vec.push(Value::Null);
                    }
                } else if let Ok(bool_val) = item.extract::<bool>() {
                    vec.push(Value::Bool(bool_val));
                } else if item.is_none() {
                    vec.push(Value::Null);
                } else {
                    vec.push(Value::String("Unsupported type".to_string()));
                }
            }
            map.insert(key_str, Value::Array(vec));
        } else {
            map.insert(key_str.clone(), Value::String(format!("Unsupported type for key: {}", key_str)));
        }
    }
    
    Ok(Value::Object(map))
}